Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • Download


nomadnet/Conversation.py 5c76d509d7fb48e6774f45fdcba792af8aabfdea (5c76d509) Text, 40.25 KB

Tff7b72import T7ee787os
Tff7b72import T7ee787re
Tff7b72import T7ee787RNS
Tff7b72import T7ee787LXMF
Tff7b72import T7ee787shutil
Tff7b72import T7ee787RNST7ee787.T7ee787vendorT7ee787.T7ee787umsgpack Tff7b72as T7ee787msgpack
Tff7b72import T7ee787nomadnet
Tff7b72from T7ee787nomadnetT7ee787.T7ee787Directory Tff7b72import Te6edf3DirectoryEntry
Tff7b72from T7ee787LXMF Tff7b72import Te6edf3display_name_from_app_data

Tff7b72class T56d364ConversationTb4b4b4:
Te6edf3cached_conversations Tff7b72= Tb4b4b4{Tb4b4b4}
Te6edf3unread_conversations Tff7b72= Tb4b4b4{Tb4b4b4}
Te6edf3created_callback Tff7b72= Tff7b72None

Te6edf3aspect_filter Tff7b72= Ta5d6ff"Ta5d6fflxmf.deliveryTa5d6ff"
Tf0883e@staticmethod
Tff7b72def Td2a8ffreceived_announceTb4b4b4(Te6edf3destination_hashTb4b4b4, Te6edf3announced_identityTb4b4b4, Te6edf3app_dataTb4b4b4)Tb4b4b4:
Te6edf3app Tff7b72= Te6edf3nomadnetTff7b72.Td2a8ffNomadNetworkAppTff7b72.Td2a8ffget_shared_instanceTb4b4b4(Tb4b4b4)

Tff7b72if Tff7b72not Te6edf3display_name_from_app_dataTb4b4b4(Te6edf3app_dataTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffIgnored invalid lxmf.delivery announce from Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)

Tff7b72if Tff7b72not Te6edf3destination_hash Tff7b72in Te6edf3appTff7b72.Td2a8ffignored_listTb4b4b4:
Te6edf3destination_hash_text Tff7b72= Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Te6edf3destination_hashTb4b4b4, Te6edf3delimitTff7b72=Tff7b72FalseTb4b4b4)
T8b949e# Check if the announced destination is in
T8b949e# our list of conversations
Tff7b72if Te6edf3destination_hash_text Tff7b72in Tb4b4b4[Te6edf3eTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72for Te6edf3e Tff7b72in Te6edf3ConversationTff7b72.Td2a8ffconversation_listTb4b4b4(Te6edf3appTb4b4b4)Tb4b4b4]Tb4b4b4:
Tff7b72if Te6edf3appTff7b72.Td2a8ffdirectoryTff7b72.Td2a8fffindTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3ConversationTff7b72.Td2a8ffcreated_callback Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3ConversationTff7b72.Td2a8ffcreated_callbackTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72if Te6edf3ConversationTff7b72.Td2a8ffcreated_callback Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3ConversationTff7b72.Td2a8ffcreated_callbackTb4b4b4(Tb4b4b4)

T8b949e# This reformats the new v0.5.0 announce data back to the expected format
T8b949e# for nomadnets storage and other handling functions.
Te6edf3dn Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffdisplay_name_from_app_dataTb4b4b4(Te6edf3app_dataTb4b4b4)
Te6edf3app_data Tff7b72= Ta5d6ffbTa5d6ff"Ta5d6ff"
Tff7b72if Te6edf3dn Tff7b72!= Tff7b72NoneTb4b4b4: Te6edf3app_data Tff7b72= Te6edf3dnTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
T8b949e# Add the announce to the directory announce
T8b949e# stream logger
Te6edf3appTff7b72.Td2a8ffdirectoryTff7b72.Td2a8fflxmf_announce_receivedTb4b4b4(Te6edf3destination_hashTb4b4b4, Te6edf3app_dataTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffIgnored announce from Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)

Tf0883e@staticmethod
Tff7b72def Td2a8ffquery_for_peerTb4b4b4(Te6edf3source_hashTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffrequest_pathTb4b4b4(Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3source_hashTb4b4b4)Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while querying network for peer identity. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tf0883e@staticmethod
Tff7b72def Td2a8ffingestTb4b4b4(Te6edf3lxmessageTb4b4b4, Te6edf3appTb4b4b4, Te6edf3originator Tff7b72= Tff7b72FalseTb4b4b4, Te6edf3delegate Tff7b72= Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3originatorTb4b4b4:
Te6edf3source_hash Tff7b72= Te6edf3lxmessageTff7b72.Td2a8ffdestination_hash
Tff7b72elseTb4b4b4:
Te6edf3source_hash Tff7b72= Te6edf3lxmessageTff7b72.Td2a8ffsource_hash
Te6edf3source_hash_path Tff7b72= Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Te6edf3source_hashTb4b4b4, Te6edf3delimitTff7b72=Tff7b72FalseTb4b4b4)

Te6edf3conversation_path Tff7b72= Te6edf3appTff7b72.Td2a8ffconversationpath Tff7b72+ Ta5d6ff"Ta5d6ff/Ta5d6ff" Tff7b72+ Te6edf3source_hash_path

Tff7b72if Tff7b72not Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Te6edf3conversation_pathTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffmakedirsTb4b4b4(Te6edf3conversation_pathTb4b4b4)
Tff7b72if Te6edf3ConversationTff7b72.Td2a8ffcreated_callback Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3ConversationTff7b72.Td2a8ffcreated_callbackTb4b4b4(Tb4b4b4)

Te6edf3ingested_path Tff7b72= Te6edf3lxmessageTff7b72.Td2a8ffwrite_to_directoryTb4b4b4(Te6edf3conversation_pathTb4b4b4)

Tff7b72tryTb4b4b4:
Te6edf3ConversationMessageTff7b72.Td2a8ffextract_attachments_from_lxmTb4b4b4(Te6edf3lxmessageTb4b4b4, Te6edf3appTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError extracting attachments: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72if Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Te6edf3source_hashTb4b4b4, Te6edf3delimitTff7b72=Tff7b72FalseTb4b4b4) Tff7b72in Te6edf3ConversationTff7b72.Td2a8ffcached_conversationsTb4b4b4:
Te6edf3conversation Tff7b72= Te6edf3ConversationTff7b72.Td2a8ffcached_conversationsTb4b4b4[Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Te6edf3source_hashTb4b4b4, Te6edf3delimitTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4]
Te6edf3conversationTff7b72.Td2a8ffscan_storageTb4b4b4(Tb4b4b4)

Tff7b72if Te6edf3source_hash Tff7b72in Te6edf3ConversationTff7b72.Td2a8ffunread_conversationsTb4b4b4:
Te6edf3ConversationTff7b72.Td2a8ffunread_conversationsTb4b4b4[Te6edf3source_hashTb4b4b4] Tff7b72+Tff7b72= T79c0ff1
Tff7b72elseTb4b4b4:
Te6edf3ConversationTff7b72.Td2a8ffunread_conversationsTb4b4b4[Te6edf3source_hashTb4b4b4] Tff7b72= T79c0ff1

Tff7b72tryTb4b4b4:
Te6edf3dirname Tff7b72= Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Te6edf3source_hashTb4b4b4, Te6edf3delimitTff7b72=Tff7b72FalseTb4b4b4)
Tff7b72with Tffa657openTb4b4b4(Te6edf3appTff7b72.Td2a8ffconversationpath Tff7b72+ Ta5d6ff"Ta5d6ff/Ta5d6ff" Tff7b72+ Te6edf3dirname Tff7b72+ Ta5d6ff"Ta5d6ff/unreadTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffwTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3ufTb4b4b4:
Te6edf3ufTff7b72.Td2a8ffwriteTb4b4b4(Tffa657strTb4b4b4(Te6edf3ConversationTff7b72.Td2a8ffunread_conversationsTb4b4b4[Te6edf3source_hashTb4b4b4]Tb4b4b4)Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72pass

Tff7b72if Te6edf3ConversationTff7b72.Td2a8ffcreated_callback Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3ConversationTff7b72.Td2a8ffcreated_callbackTb4b4b4(Tb4b4b4)

Tff7b72return Te6edf3ingested_path

Tf0883e@staticmethod
Tff7b72def Td2a8ffconversation_listTb4b4b4(Te6edf3appTb4b4b4)Tb4b4b4:
Te6edf3conversations Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3dirname Tff7b72in Te6edf3osTff7b72.Td2a8fflistdirTb4b4b4(Te6edf3appTff7b72.Td2a8ffconversationpathTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657lenTb4b4b4(Te6edf3dirnameTb4b4b4) Tff7b72== Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffTRUNCATED_HASHLENGTHTff7b72/Tff7b72/T79c0ff8Tff7b72*T79c0ff2 Tff7b72and Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Te6edf3appTff7b72.Td2a8ffconversationpath Tff7b72+ Ta5d6ff"Ta5d6ff/Ta5d6ff" Tff7b72+ Te6edf3dirnameTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3source_hash_text Tff7b72= Te6edf3dirname
Te6edf3source_hash Tff7b72= Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3dirnameTb4b4b4)
Te6edf3app_data Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffrecall_app_dataTb4b4b4(Te6edf3source_hashTb4b4b4)
Te6edf3display_name Tff7b72= Te6edf3appTff7b72.Td2a8ffdirectoryTff7b72.Td2a8ffdisplay_nameTb4b4b4(Te6edf3source_hashTb4b4b4)

Te6edf3unread Tff7b72= T79c0ff0
Tff7b72if Te6edf3source_hash Tff7b72in Te6edf3ConversationTff7b72.Td2a8ffunread_conversationsTb4b4b4:
Te6edf3unread Tff7b72= Te6edf3ConversationTff7b72.Td2a8ffunread_conversationsTb4b4b4[Te6edf3source_hashTb4b4b4]
Tff7b72elif Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3appTff7b72.Td2a8ffconversationpath Tff7b72+ Ta5d6ff"Ta5d6ff/Ta5d6ff" Tff7b72+ Te6edf3dirname Tff7b72+ Ta5d6ff"Ta5d6ff/unreadTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72with Tffa657openTb4b4b4(Te6edf3appTff7b72.Td2a8ffconversationpath Tff7b72+ Ta5d6ff"Ta5d6ff/Ta5d6ff" Tff7b72+ Te6edf3dirname Tff7b72+ Ta5d6ff"Ta5d6ff/unreadTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffrTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3ufTb4b4b4:
Te6edf3content Tff7b72= Te6edf3ufTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Te6edf3unread Tff7b72= Tffa657intTb4b4b4(Te6edf3contentTb4b4b4) Tff7b72if Te6edf3content Tff7b72else T79c0ff1
Tff7b72except Tf85149ExceptionTb4b4b4:
Te6edf3unread Tff7b72= T79c0ff1
Te6edf3ConversationTff7b72.Td2a8ffunread_conversationsTb4b4b4[Te6edf3source_hashTb4b4b4] Tff7b72= Te6edf3unread

Tff7b72if Te6edf3display_name Tff7b72== Tff7b72None Tff7b72and Te6edf3app_dataTb4b4b4:
Te6edf3display_name Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffdisplay_name_from_app_dataTb4b4b4(Te6edf3app_dataTb4b4b4)

Tff7b72if Te6edf3display_name Tff7b72== Tff7b72NoneTb4b4b4:
Te6edf3sort_name Tff7b72= Ta5d6ff"Ta5d6ff"
Tff7b72elseTb4b4b4:
Te6edf3sort_name Tff7b72= Te6edf3display_name
Te6edf3trust_level Tff7b72= Te6edf3appTff7b72.Td2a8ffdirectoryTff7b72.Td2a8fftrust_levelTb4b4b4(Te6edf3source_hashTb4b4b4, Te6edf3display_nameTb4b4b4)

Te6edf3conversation_dir Tff7b72= Te6edf3appTff7b72.Td2a8ffconversationpath Tff7b72+ Ta5d6ff"Ta5d6ff/Ta5d6ff" Tff7b72+ Te6edf3dirname
Tff7b72tryTb4b4b4:
Te6edf3last_activity Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffgetmtimeTb4b4b4(Te6edf3conversation_dirTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Te6edf3last_activity Tff7b72= T79c0ff0

Te6edf3entry Tff7b72= Tb4b4b4(Te6edf3source_hash_textTb4b4b4, Te6edf3display_nameTb4b4b4, Te6edf3trust_levelTb4b4b4, Te6edf3sort_nameTb4b4b4, Te6edf3unreadTb4b4b4, Te6edf3last_activityTb4b4b4)
Te6edf3conversationsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3entryTb4b4b4)

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while loading conversation Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3dirnameTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff, skipping it. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Te6edf3conversationsTff7b72.Td2a8ffsortTb4b4b4(Te6edf3keyTff7b72=Tff7b72lambda Te6edf3eTb4b4b4: Te6edf3eTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4, Te6edf3reverseTff7b72=Tff7b72TrueTb4b4b4)

Tff7b72return Te6edf3conversations

Tf0883e@staticmethod
Tff7b72def Td2a8ffcache_conversationTb4b4b4(Te6edf3conversationTb4b4b4)Tb4b4b4:
Te6edf3ConversationTff7b72.Td2a8ffcached_conversationsTb4b4b4[Te6edf3conversationTff7b72.Td2a8ffsource_hashTb4b4b4] Tff7b72= Te6edf3conversation

Tf0883e@staticmethod
Tff7b72def Td2a8ffdelete_conversationTb4b4b4(Te6edf3source_hash_pathTb4b4b4, Te6edf3appTb4b4b4)Tb4b4b4:
Te6edf3conversation_path Tff7b72= Te6edf3appTff7b72.Td2a8ffconversationpath Tff7b72+ Ta5d6ff"Ta5d6ff/Ta5d6ff" Tff7b72+ Te6edf3source_hash_path

Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Te6edf3conversation_pathTb4b4b4)Tb4b4b4:
Te6edf3shutilTff7b72.Td2a8ffrmtreeTb4b4b4(Te6edf3conversation_pathTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCould not remove conversation at Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3conversation_pathTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3source_hashTb4b4b4, Te6edf3appTb4b4b4, Te6edf3initiatorTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffapp Tff7b72= Te6edf3app
Tff7b72selfTff7b72.Td2a8ffsource_hash Tff7b72= Te6edf3source_hash
Tff7b72selfTff7b72.Td2a8ffsend_destination Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffmessages Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffmessages_path Tff7b72= Te6edf3appTff7b72.Td2a8ffconversationpath Tff7b72+ Ta5d6ff"Ta5d6ff/Ta5d6ff" Tff7b72+ Te6edf3source_hash
Tff7b72selfTff7b72.Td2a8ffmessages_load_time Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffsource_known Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffsource_trusted Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffsource_blocked Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffunread Tff7b72= Tff7b72False

Tff7b72selfTff7b72.Td2a8ff__changed_callback Tff7b72= Tff7b72None

Tff7b72if Tff7b72not Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffrecallTb4b4b4(Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Tff7b72selfTff7b72.Td2a8ffsource_hashTb4b4b4)Tb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffrequest_pathTb4b4b4(Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3source_hashTb4b4b4)Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffsource_identity Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffrecallTb4b4b4(Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Tff7b72selfTff7b72.Td2a8ffsource_hashTb4b4b4)Tb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffsource_identityTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffsource_known Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffsend_destination Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTb4b4b4(Tff7b72selfTff7b72.Td2a8ffsource_identityTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffOUTTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffSINGLETb4b4b4, Ta5d6ff"Ta5d6fflxmfTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffdeliveryTa5d6ff"Tb4b4b4)

Tff7b72if Te6edf3initiatorTb4b4b4:
Tff7b72if Tff7b72not Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessages_pathTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffmakedirsTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessages_pathTb4b4b4)
Tff7b72if Te6edf3ConversationTff7b72.Td2a8ffcreated_callback Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3ConversationTff7b72.Td2a8ffcreated_callbackTb4b4b4(Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffscan_storageTb4b4b4(Tb4b4b4)

Tff7b72selfTff7b72.Td2a8fftrust_level Tff7b72= Te6edf3appTff7b72.Td2a8ffdirectoryTff7b72.Td2a8fftrust_levelTb4b4b4(Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Tff7b72selfTff7b72.Td2a8ffsource_hashTb4b4b4)Tb4b4b4)

Te6edf3ConversationTff7b72.Td2a8ffcache_conversationTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72def Td2a8ffscan_storageTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3old_len Tff7b72= Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessagesTb4b4b4)
Te6edf3existing Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72for Te6edf3msg Tff7b72in Tff7b72selfTff7b72.Td2a8ffmessagesTb4b4b4:
Te6edf3existingTb4b4b4[Te6edf3msgTff7b72.Td2a8fffile_pathTb4b4b4] Tff7b72= Te6edf3msg

Te6edf3index Tff7b72= Te6edf3ConversationMessageTff7b72.Td2a8ffread_indexTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessages_pathTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffmessages Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3filename Tff7b72in Te6edf3osTff7b72.Td2a8fflistdirTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessages_pathTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657lenTb4b4b4(Te6edf3filenameTb4b4b4) Tff7b72== Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffHASHLENGTHTff7b72/Tff7b72/T79c0ff8Tff7b72*T79c0ff2Tb4b4b4:
Te6edf3message_path Tff7b72= Tff7b72selfTff7b72.Td2a8ffmessages_path Tff7b72+ Ta5d6ff"Ta5d6ff/Ta5d6ff" Tff7b72+ Te6edf3filename
Tff7b72if Te6edf3message_path Tff7b72in Te6edf3existingTb4b4b4:
Te6edf3old_msg Tff7b72= Te6edf3existingTb4b4b4[Te6edf3message_pathTb4b4b4]
Tff7b72tryTb4b4b4:
Te6edf3current_mtime Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffgetmtimeTb4b4b4(Te6edf3message_pathTb4b4b4)
Tff7b72if Te6edf3current_mtime Tff7b72> Te6edf3old_msgTff7b72.Td2a8ffsort_timestampTb4b4b4:
Te6edf3old_msgTff7b72.Td2a8ff_cached_state Tff7b72= Tff7b72None
Te6edf3old_msgTff7b72.Td2a8ff_cached_method Tff7b72= Tff7b72None
Te6edf3old_msgTff7b72.Td2a8ffsort_timestamp Tff7b72= Te6edf3current_mtime
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72pass
Tff7b72selfTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3old_msgTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3msg Tff7b72= Te6edf3ConversationMessageTb4b4b4(Te6edf3message_pathTb4b4b4)
Tff7b72if Te6edf3filename Tff7b72in Te6edf3indexTb4b4b4:
Te6edf3msgTff7b72.Td2a8ffrestore_from_indexTb4b4b4(Te6edf3indexTb4b4b4[Te6edf3filenameTb4b4b4]Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msgTb4b4b4)

Te6edf3new_len Tff7b72= Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessagesTb4b4b4)

Te6edf3needs_index_update Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3msg Tff7b72in Tff7b72selfTff7b72.Td2a8ffmessagesTb4b4b4:
Te6edf3filename Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffbasenameTb4b4b4(Te6edf3msgTff7b72.Td2a8fffile_pathTb4b4b4)
Tff7b72if Te6edf3msgTff7b72.Td2a8ff_cached_state Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72if Te6edf3filename Tff7b72not Tff7b72in Te6edf3indexTb4b4b4:
Te6edf3needs_index_updateTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msgTb4b4b4)
Tff7b72elif Ta5d6ff"Ta5d6ffcontentTa5d6ff" Tff7b72not Tff7b72in Te6edf3indexTb4b4b4[Te6edf3filenameTb4b4b4]Tb4b4b4:
Te6edf3needs_index_updateTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msgTb4b4b4)
Tff7b72if Te6edf3needs_index_updateTb4b4b4:
Te6edf3ConversationMessageTff7b72.Td2a8ffwrite_indexTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessages_pathTb4b4b4, Te6edf3needs_index_updateTb4b4b4)

Tff7b72if Te6edf3new_len Tff7b72> Te6edf3old_lenTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffunread Tff7b72= Tff7b72True

Tff7b72if Tff7b72selfTff7b72.Td2a8ff__changed_callback Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff__changed_callbackTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72def Td2a8ffpurge_failedTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3purged_messages Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3conversation_message Tff7b72in Tff7b72selfTff7b72.Td2a8ffmessagesTb4b4b4:
Tff7b72if Te6edf3conversation_messageTff7b72.Td2a8ffget_stateTb4b4b4(Tb4b4b4) Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffFAILEDTb4b4b4:
Te6edf3purged_messagesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3conversation_messageTb4b4b4)
Te6edf3conversation_messageTff7b72.Td2a8ffpurgeTb4b4b4(Tb4b4b4)

Tff7b72for Te6edf3purged_message Tff7b72in Te6edf3purged_messagesTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3purged_messageTb4b4b4)

Tff7b72def Td2a8ffclear_historyTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3purged_messages Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3conversation_message Tff7b72in Tff7b72selfTff7b72.Td2a8ffmessagesTb4b4b4:
Te6edf3purged_messagesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3conversation_messageTb4b4b4)
Te6edf3conversation_messageTff7b72.Td2a8ffpurgeTb4b4b4(Tb4b4b4)

Tff7b72for Te6edf3purged_message Tff7b72in Te6edf3purged_messagesTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3purged_messageTb4b4b4)

Tff7b72def Td2a8ffregister_changed_callbackTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3callbackTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff__changed_callback Tff7b72= Te6edf3callback

Tff7b72def Td2a8ffsendTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3contentTff7b72=Ta5d6ff"Ta5d6ff"Tb4b4b4, Te6edf3titleTff7b72=Ta5d6ff"Ta5d6ff"Tb4b4b4, Te6edf3fieldsTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffsend_destinationTb4b4b4:
Te6edf3dest Tff7b72= Tff7b72selfTff7b72.Td2a8ffsend_destination
Te6edf3source Tff7b72= Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8fflxmf_destination
Te6edf3desired_method Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDIRECT
Tff7b72if Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffdirectoryTff7b72.Td2a8ffpreferred_deliveryTb4b4b4(Te6edf3destTff7b72.Td2a8ffhashTb4b4b4) Tff7b72== Te6edf3DirectoryEntryTff7b72.Td2a8ffPROPAGATEDTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffget_outbound_propagation_nodeTb4b4b4(Tb4b4b4) Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3desired_method Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffPROPAGATED
Tff7b72elseTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffdelivery_link_availableTb4b4b4(Te6edf3destTff7b72.Td2a8ffhashTb4b4b4) Tff7b72and Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffcurrent_ratchet_idTb4b4b4(Te6edf3destTff7b72.Td2a8ffhashTb4b4b4) Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffHave ratchet for Tffd700{Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3destTff7b72.Td2a8ffhashTb4b4b4)Tffd700}Ta5d6ff, requesting opportunistic delivery of messageTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3desired_method Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffOPPORTUNISTIC

Te6edf3dest_is_trusted Tff7b72= Tff7b72False
Tff7b72if Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffdirectoryTff7b72.Td2a8fftrust_levelTb4b4b4(Te6edf3destTff7b72.Td2a8ffhashTb4b4b4) Tff7b72== Te6edf3DirectoryEntryTff7b72.Td2a8ffTRUSTEDTb4b4b4:
Te6edf3dest_is_trusted Tff7b72= Tff7b72True

Te6edf3lxm Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffLXMessageTb4b4b4(Te6edf3destTb4b4b4, Te6edf3sourceTb4b4b4, Te6edf3contentTb4b4b4, Te6edf3titleTff7b72=Te6edf3titleTb4b4b4, Te6edf3fieldsTff7b72=Te6edf3fieldsTb4b4b4, Te6edf3desired_methodTff7b72=Te6edf3desired_methodTb4b4b4, Te6edf3include_ticketTff7b72=Te6edf3dest_is_trustedTb4b4b4)
Te6edf3lxmTff7b72.Td2a8ffregister_delivery_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessage_notificationTb4b4b4)
Te6edf3lxmTff7b72.Td2a8ffregister_failed_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffmessage_notificationTb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffget_outbound_propagation_nodeTb4b4b4(Tb4b4b4) Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3lxmTff7b72.Td2a8fftry_propagation_on_fail Tff7b72= Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8fftry_propagation_on_fail

Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffhandle_outboundTb4b4b4(Te6edf3lxmTb4b4b4)

Te6edf3message_path Tff7b72= Te6edf3ConversationTff7b72.Td2a8ffingestTb4b4b4(Te6edf3lxmTb4b4b4, Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Te6edf3originatorTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3ConversationMessageTb4b4b4(Te6edf3message_pathTb4b4b4)Tb4b4b4)

Tff7b72return Tff7b72True
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffDestination is not known, cannot create LXMF Message.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Tff7b72return Tff7b72False

Tff7b72def Td2a8ffpaper_outputTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3contentTff7b72=Ta5d6ff"Ta5d6ff"Tb4b4b4, Te6edf3titleTff7b72=Ta5d6ff"Ta5d6ff"Tb4b4b4, Te6edf3modeTff7b72=Ta5d6ff"Ta5d6ffprint_qrTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffsend_destinationTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3dest Tff7b72= Tff7b72selfTff7b72.Td2a8ffsend_destination
Te6edf3source Tff7b72= Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8fflxmf_destination
Te6edf3desired_method Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffPAPER

Te6edf3lxm Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffLXMessageTb4b4b4(Te6edf3destTb4b4b4, Te6edf3sourceTb4b4b4, Te6edf3contentTb4b4b4, Te6edf3titleTff7b72=Te6edf3titleTb4b4b4, Te6edf3desired_methodTff7b72=Te6edf3desired_methodTb4b4b4)

Tff7b72if Te6edf3mode Tff7b72== Ta5d6ff"Ta5d6ffprint_qrTa5d6ff"Tb4b4b4:
Te6edf3qr_code Tff7b72= Te6edf3lxmTff7b72.Td2a8ffas_qrTb4b4b4(Tb4b4b4)
Te6edf3qr_tmp_path Tff7b72= Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8fftmpfilespathTff7b72+Ta5d6ff"Ta5d6ff/Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Te6edf3lxmTff7b72.Td2a8ffhashTb4b4b4, Te6edf3delimitTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4)
Te6edf3qr_codeTff7b72.Td2a8ffsaveTb4b4b4(Te6edf3qr_tmp_pathTb4b4b4)

Te6edf3print_result Tff7b72= Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffprint_fileTb4b4b4(Te6edf3qr_tmp_pathTb4b4b4)
Te6edf3osTff7b72.Td2a8ffunlinkTb4b4b4(Te6edf3qr_tmp_pathTb4b4b4)
Tff7b72if Te6edf3print_resultTb4b4b4:
Te6edf3message_path Tff7b72= Te6edf3ConversationTff7b72.Td2a8ffingestTb4b4b4(Te6edf3lxmTb4b4b4, Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Te6edf3originatorTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3ConversationMessageTb4b4b4(Te6edf3message_pathTb4b4b4)Tb4b4b4)

Tff7b72return Te6edf3print_result

Tff7b72elif Te6edf3mode Tff7b72== Ta5d6ff"Ta5d6ffsave_qrTa5d6ff"Tb4b4b4:
Te6edf3qr_code Tff7b72= Te6edf3lxmTff7b72.Td2a8ffas_qrTb4b4b4(Tb4b4b4)
Te6edf3qr_save_path Tff7b72= Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffdownloads_pathTff7b72+Ta5d6ff"Ta5d6ff/LXM_Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Te6edf3lxmTff7b72.Td2a8ffhashTb4b4b4, Te6edf3delimitTff7b72=Tff7b72FalseTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff.pngTa5d6ff"Tb4b4b4)
Te6edf3qr_codeTff7b72.Td2a8ffsaveTb4b4b4(Te6edf3qr_save_pathTb4b4b4)
Te6edf3message_path Tff7b72= Te6edf3ConversationTff7b72.Td2a8ffingestTb4b4b4(Te6edf3lxmTb4b4b4, Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Te6edf3originatorTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3ConversationMessageTb4b4b4(Te6edf3message_pathTb4b4b4)Tb4b4b4)
Tff7b72return Te6edf3qr_save_path

Tff7b72elif Te6edf3mode Tff7b72== Ta5d6ff"Ta5d6ffsave_uriTa5d6ff"Tb4b4b4:
Te6edf3lxm_uri Tff7b72= Te6edf3lxmTff7b72.Td2a8ffas_uriTb4b4b4(Tb4b4b4)Tff7b72+Ta5d6ff"Tffea00\nTa5d6ff"
Te6edf3uri_save_path Tff7b72= Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffdownloads_pathTff7b72+Ta5d6ff"Ta5d6ff/LXM_Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Te6edf3lxmTff7b72.Td2a8ffhashTb4b4b4, Te6edf3delimitTff7b72=Tff7b72FalseTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff.txtTa5d6ff"Tb4b4b4)
Tff7b72with Tffa657openTb4b4b4(Te6edf3uri_save_pathTb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Te6edf3fTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3lxm_uriTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4)

Te6edf3message_path Tff7b72= Te6edf3ConversationTff7b72.Td2a8ffingestTb4b4b4(Te6edf3lxmTb4b4b4, Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Te6edf3originatorTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3ConversationMessageTb4b4b4(Te6edf3message_pathTb4b4b4)Tb4b4b4)
Tff7b72return Te6edf3uri_save_path

Tff7b72elif Te6edf3mode Tff7b72== Ta5d6ff"Ta5d6ffreturn_uriTa5d6ff"Tb4b4b4:
Tff7b72return Te6edf3lxmTff7b72.Td2a8ffas_uriTb4b4b4(Tb4b4b4)

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffAn error occurred while generating paper message, the contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72return Tff7b72False

Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffDestination is not known, cannot create LXMF Message.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Tff7b72return Tff7b72False

Tff7b72def Td2a8ffmessage_notificationTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3messageTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3messageTff7b72.Td2a8ffstate Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffFAILED Tff7b72and Tffa657hasattrTb4b4b4(Te6edf3messageTb4b4b4, Ta5d6ff"Ta5d6fftry_propagation_on_failTa5d6ff"Tb4b4b4) Tff7b72and Te6edf3messageTff7b72.Td2a8fftry_propagation_on_failTb4b4b4:
Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3messageTb4b4b4, Ta5d6ff"Ta5d6ffstamp_generation_failedTa5d6ff"Tb4b4b4) Tff7b72and Te6edf3messageTff7b72.Td2a8ffstamp_generation_failed Tff7b72== Tff7b72TrueTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffCould not send Tffd700{Te6edf3messageTffd700}Ta5d6ff due to a stamp generation failureTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffDirect delivery of Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3messageTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff failed. Retrying as propagated message.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Te6edf3messageTff7b72.Td2a8fftry_propagation_on_fail Tff7b72= Tff7b72None
Te6edf3messageTff7b72.Td2a8ffdelivery_attempts Tff7b72= T79c0ff0
Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3messageTb4b4b4, Ta5d6ff"Ta5d6ffnext_delivery_attemptTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72del Te6edf3messageTff7b72.Td2a8ffnext_delivery_attempt
Te6edf3messageTff7b72.Td2a8ffpacked Tff7b72= Tff7b72None
Te6edf3messageTff7b72.Td2a8ffdesired_method Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffPROPAGATED
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffhandle_outboundTb4b4b4(Te6edf3messageTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3message_path Tff7b72= Te6edf3ConversationTff7b72.Td2a8ffingestTb4b4b4(Te6edf3messageTb4b4b4, Tff7b72selfTff7b72.Td2a8ffappTb4b4b4, Te6edf3originatorTff7b72=Tff7b72TrueTb4b4b4)

Tff7b72def Tff7b72__str__Tb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3string Tff7b72= Tff7b72selfTff7b72.Td2a8ffsource_hash

T8b949e# TODO: Remove this
T8b949e# if self.source_identity:
T8b949e# if self.source_identity.app_data:
T8b949e# # TODO: Sanitise for viewing, or just clean this
T8b949e# string += " | "+self.source_identity.app_data.decode("utf-8")

Tff7b72return Te6edf3string



Tff7b72class T56d364ConversationMessageTb4b4b4:
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3file_pathTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8fffile_path Tff7b72= Te6edf3file_path
Tff7b72selfTff7b72.Td2a8ffloaded Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8fftimestamp Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8fflxm Tff7b72= Tff7b72None

Tff7b72selfTff7b72.Td2a8ff_cached_hash Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_cached_state Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_cached_title Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_cached_content Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_cached_source_hash Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_cached_transport_encrypted Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_cached_transport_encryption Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_cached_signature_validated Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_cached_unverified_reason Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_cached_method Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_cached_has_attachments Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_cached_attachment_names Tff7b72= Tff7b72None

Tff7b72selfTff7b72.Td2a8ffsort_timestamp Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffgetmtimeTb4b4b4(Te6edf3file_pathTb4b4b4) Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3file_pathTb4b4b4) Tff7b72else T79c0ff0

Te6edf3filename Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffbasenameTb4b4b4(Te6edf3file_pathTb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3filenameTb4b4b4) Tff7b72== Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffHASHLENGTHTff7b72/Tff7b72/T79c0ff8Tff7b72*T79c0ff2Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_cached_hash Tff7b72= Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3filenameTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72pass

Tff7b72def Td2a8ffloadTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72with Tffa657openTb4b4b4(Tff7b72selfTff7b72.Td2a8fffile_pathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3lxm_fileTb4b4b4:
Tff7b72selfTff7b72.Td2a8fflxm Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffunpack_from_fileTb4b4b4(Te6edf3lxm_fileTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffloaded Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8fftimestamp Tff7b72= Tff7b72selfTff7b72.Td2a8fflxmTff7b72.Td2a8fftimestamp
Tff7b72selfTff7b72.Td2a8ffsort_timestamp Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffgetmtimeTb4b4b4(Tff7b72selfTff7b72.Td2a8fffile_pathTb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8fflxmTff7b72.Td2a8ffstate Tff7b72> Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffGENERATING Tff7b72and Tff7b72selfTff7b72.Td2a8fflxmTff7b72.Td2a8ffstate Tff7b72< Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffSENTTb4b4b4:
Te6edf3found Tff7b72= Tff7b72False

Tff7b72for Te6edf3pending Tff7b72in Te6edf3nomadnetTff7b72.Td2a8ffNomadNetworkAppTff7b72.Td2a8ffget_shared_instanceTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffpending_outboundTb4b4b4:
Tff7b72if Te6edf3pendingTff7b72.Td2a8ffhash Tff7b72== Tff7b72selfTff7b72.Td2a8fflxmTff7b72.Td2a8ffhashTb4b4b4:
Te6edf3found Tff7b72= Tff7b72True

Tff7b72for Te6edf3pending_id Tff7b72in Te6edf3nomadnetTff7b72.Td2a8ffNomadNetworkAppTff7b72.Td2a8ffget_shared_instanceTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffpending_deferred_stampsTb4b4b4:
Tff7b72if Te6edf3pending_id Tff7b72== Tff7b72selfTff7b72.Td2a8fflxmTff7b72.Td2a8ffhashTb4b4b4:
Te6edf3found Tff7b72= Tff7b72True

Tff7b72if Tff7b72not Te6edf3foundTb4b4b4:
Tff7b72selfTff7b72.Td2a8fflxmTff7b72.Td2a8ffstate Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffFAILED

Tff7b72if Tff7b72selfTff7b72.Td2a8ff_cached_hash Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_cached_hash Tff7b72= Tff7b72selfTff7b72.Td2a8fflxmTff7b72.Td2a8ffhash
Tff7b72selfTff7b72.Td2a8ff_cached_state Tff7b72= Tff7b72selfTff7b72.Td2a8fflxmTff7b72.Td2a8ffstate
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_cached_source_hash Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_cached_source_hash Tff7b72= Tff7b72selfTff7b72.Td2a8fflxmTff7b72.Td2a8ffsource_hash
Tff7b72selfTff7b72.Td2a8ff_cached_transport_encrypted Tff7b72= Tff7b72selfTff7b72.Td2a8fflxmTff7b72.Td2a8fftransport_encrypted
Tff7b72selfTff7b72.Td2a8ff_cached_transport_encryption Tff7b72= Tff7b72selfTff7b72.Td2a8fflxmTff7b72.Td2a8fftransport_encryption
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_cached_signature_validated Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_cached_signature_validated Tff7b72= Tff7b72selfTff7b72.Td2a8fflxmTff7b72.Td2a8ffsignature_validated
Tff7b72selfTff7b72.Td2a8ff_cached_method Tff7b72= Tff7b72selfTff7b72.Td2a8fflxmTff7b72.Td2a8ffmethod
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_cached_unverified_reason Tff7b72is Tff7b72None Tff7b72and Tffa657hasattrTb4b4b4(Tff7b72selfTff7b72.Td2a8fflxmTb4b4b4, Ta5d6ff"Ta5d6ffunverified_reasonTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_cached_unverified_reason Tff7b72= Tff7b72selfTff7b72.Td2a8fflxmTff7b72.Td2a8ffunverified_reason
Tff7b72selfTff7b72.Td2a8ff_cached_title Tff7b72= Tff7b72selfTff7b72.Td2a8fflxmTff7b72.Td2a8fftitle_as_stringTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_cached_content Tff7b72= Tff7b72selfTff7b72.Td2a8fflxmTff7b72.Td2a8ffcontent_as_stringTb4b4b4(Tb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ff_cached_has_attachments Tff7b72is Tff7b72NoneTb4b4b4:
Te6edf3found_in_fields Tff7b72= Tff7b72False
Te6edf3fields Tff7b72= Tff7b72None
Tff7b72if Tffa657hasattrTb4b4b4(Tff7b72selfTff7b72.Td2a8fflxmTb4b4b4, Ta5d6ff"Ta5d6ffget_fieldsTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3fields Tff7b72= Tff7b72selfTff7b72.Td2a8fflxmTff7b72.Td2a8ffget_fieldsTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3fields Tff7b72and Tffa657isinstanceTb4b4b4(Te6edf3fieldsTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Te6edf3found_in_fields Tff7b72= Tb4b4b4(
Te6edf3LXMFTff7b72.Td2a8ffFIELD_FILE_ATTACHMENTS Tff7b72in Te6edf3fields
Tff7b72or Te6edf3LXMFTff7b72.Td2a8ffFIELD_IMAGE Tff7b72in Te6edf3fields
Tff7b72or Te6edf3LXMFTff7b72.Td2a8ffFIELD_AUDIO Tff7b72in Te6edf3fields
Tb4b4b4)
Tff7b72if Te6edf3found_in_fieldsTb4b4b4:
Te6edf3names Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3file_atts Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffFIELD_FILE_ATTACHMENTSTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4)
Tff7b72for Te6edf3idxTb4b4b4, Te6edf3att Tff7b72in Tffa657enumerateTb4b4b4(Te6edf3file_attsTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3attTb4b4b4, Tffa657listTb4b4b4) Tff7b72and Tffa657lenTb4b4b4(Te6edf3attTb4b4b4) Tff7b72>Tff7b72= T79c0ff2Tb4b4b4:
Te6edf3size Tff7b72= Tffa657lenTb4b4b4(Te6edf3attTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4) Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3attTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4, Tffa657bytesTb4b4b4) Tff7b72else T79c0ff0
Te6edf3safe Tff7b72= Te6edf3ConversationMessageTff7b72.Td2a8ffsafe_attachment_nameTb4b4b4(Te6edf3attTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4, Te6edf3fallbackTff7b72=Ta5d6ff"Ta5d6ffattachment_Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3idxTb4b4b4)Tb4b4b4)
Te6edf3namesTff7b72.Td2a8ffappendTb4b4b4(Tb4b4b4(Ta5d6ff"Ta5d6fffileTa5d6ff"Tb4b4b4, Te6edf3safeTb4b4b4, Te6edf3sizeTb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3LXMFTff7b72.Td2a8ffFIELD_IMAGE Tff7b72in Te6edf3fieldsTb4b4b4:
Te6edf3fmtTb4b4b4, Te6edf3data Tff7b72= Te6edf3ConversationMessageTff7b72.Td2a8ff_unpack_media_fieldTb4b4b4(Te6edf3fieldsTb4b4b4[Te6edf3LXMFTff7b72.Td2a8ffFIELD_IMAGETb4b4b4]Tb4b4b4)
Tff7b72if Te6edf3dataTb4b4b4:
Te6edf3size Tff7b72= Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4)
Te6edf3ext Tff7b72= Te6edf3ConversationMessageTff7b72.Td2a8ff_ext_from_media_formatTb4b4b4(Te6edf3fmtTb4b4b4, Te6edf3dataTb4b4b4)
Te6edf3safe Tff7b72= Te6edf3ConversationMessageTff7b72.Td2a8ffsafe_attachment_nameTb4b4b4(Ta5d6ff"Ta5d6ffimageTa5d6ff"Tff7b72+Te6edf3extTb4b4b4, Te6edf3fallbackTff7b72=Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4)
Te6edf3namesTff7b72.Td2a8ffappendTb4b4b4(Tb4b4b4(Ta5d6ff"Ta5d6fffileTa5d6ff"Tb4b4b4, Te6edf3safeTb4b4b4, Te6edf3sizeTb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3LXMFTff7b72.Td2a8ffFIELD_AUDIO Tff7b72in Te6edf3fieldsTb4b4b4:
Te6edf3fmtTb4b4b4, Te6edf3data Tff7b72= Te6edf3ConversationMessageTff7b72.Td2a8ff_unpack_media_fieldTb4b4b4(Te6edf3fieldsTb4b4b4[Te6edf3LXMFTff7b72.Td2a8ffFIELD_AUDIOTb4b4b4]Tb4b4b4)
Tff7b72if Te6edf3dataTb4b4b4:
Te6edf3size Tff7b72= Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4)
Te6edf3ext Tff7b72= Te6edf3ConversationMessageTff7b72.Td2a8ff_ext_from_media_formatTb4b4b4(Te6edf3fmtTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3is_audioTff7b72=Tff7b72TrueTb4b4b4)
Te6edf3safe Tff7b72= Te6edf3ConversationMessageTff7b72.Td2a8ffsafe_attachment_nameTb4b4b4(Ta5d6ff"Ta5d6ffaudioTa5d6ff"Tff7b72+Te6edf3extTb4b4b4, Te6edf3fallbackTff7b72=Ta5d6ff"Ta5d6ffaudioTa5d6ff"Tb4b4b4)
Te6edf3namesTff7b72.Td2a8ffappendTb4b4b4(Tb4b4b4(Ta5d6ff"Ta5d6fffileTa5d6ff"Tb4b4b4, Te6edf3safeTb4b4b4, Te6edf3sizeTb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_cached_has_attachments Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ff_cached_attachment_names Tff7b72= Te6edf3names

Tff7b72if Tff7b72not Te6edf3found_in_fieldsTb4b4b4:
Te6edf3att_dir Tff7b72= Tff7b72selfTff7b72.Td2a8ff_attachment_dirTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3att_dir Tff7b72and Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Te6edf3att_dirTb4b4b4)Tb4b4b4:
Te6edf3manifest Tff7b72= Tff7b72selfTff7b72.Td2a8ff_read_attachment_manifestTb4b4b4(Te6edf3att_dirTb4b4b4)
Tff7b72if Te6edf3manifest Tff7b72and Ta5d6ff"Ta5d6fffilesTa5d6ff" Tff7b72in Te6edf3manifest Tff7b72and Tffa657lenTb4b4b4(Te6edf3manifestTb4b4b4[Ta5d6ff"Ta5d6fffilesTa5d6ff"Tb4b4b4]Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3names Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3entry Tff7b72in Te6edf3manifestTb4b4b4[Ta5d6ff"Ta5d6fffilesTa5d6ff"Tb4b4b4]Tb4b4b4:
Te6edf3namesTff7b72.Td2a8ffappendTb4b4b4(Tb4b4b4(Ta5d6ff"Ta5d6fffileTa5d6ff"Tb4b4b4, Te6edf3entryTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4]Tb4b4b4, Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffsizeTa5d6ff"Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_cached_has_attachments Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ff_cached_attachment_names Tff7b72= Te6edf3names
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_cached_has_attachments Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_cached_attachment_names Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_cached_has_attachments Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_cached_attachment_names Tff7b72= Tb4b4b4[Tb4b4b4]

Tff7b72tryTb4b4b4:
Te6edf3app Tff7b72= Te6edf3nomadnetTff7b72.Td2a8ffNomadNetworkAppTff7b72.Td2a8ffget_shared_instanceTb4b4b4(Tb4b4b4)
Te6edf3ConversationMessageTff7b72.Td2a8ffextract_attachments_from_lxmTb4b4b4(Tff7b72selfTff7b72.Td2a8fflxmTb4b4b4, Te6edf3appTb4b4b4)
Te6edf3ConversationMessageTff7b72.Td2a8ffstrip_attachments_from_fileTb4b4b4(Tff7b72selfTff7b72.Td2a8fffile_pathTb4b4b4, Te6edf3appTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72pass

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while loading LXMF message Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTff7b72.Td2a8fffile_pathTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff from disk. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72def Td2a8ffunloadTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffloaded Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8fflxm Tff7b72= Tff7b72None

Tff7b72def Td2a8ffpurgeTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffunloadTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Tff7b72selfTff7b72.Td2a8fffile_pathTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffunlinkTb4b4b4(Tff7b72selfTff7b72.Td2a8fffile_pathTb4b4b4)

Tff7b72def Td2a8ffget_timestampTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8fftimestamp Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8fftimestamp
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffloadedTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffloadTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72selfTff7b72.Td2a8fftimestamp

Tff7b72def Td2a8ffget_titleTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_cached_title Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_cached_title
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffloadedTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffloadTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_cached_title Tff7b72if Tff7b72selfTff7b72.Td2a8ff_cached_title Tff7b72is Tff7b72not Tff7b72None Tff7b72else Ta5d6ff"Ta5d6ff"

Tff7b72def Td2a8ffget_contentTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_cached_content Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_cached_content
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffloadedTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffloadTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_cached_content Tff7b72if Tff7b72selfTff7b72.Td2a8ff_cached_content Tff7b72is Tff7b72not Tff7b72None Tff7b72else Ta5d6ff"Ta5d6ff"

Tff7b72def Td2a8ffget_hashTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_cached_hash Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_cached_hash
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffloadedTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffloadTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_cached_hash

Tff7b72def Td2a8ffget_stateTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_cached_state Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_cached_state
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffloadedTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffloadTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_cached_state

Tff7b72def Td2a8ffget_transport_encryptionTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_cached_transport_encryption Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_cached_transport_encryption
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffloadedTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffloadTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_cached_transport_encryption

Tff7b72def Td2a8ffget_transport_encryptedTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_cached_transport_encrypted Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_cached_transport_encrypted
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffloadedTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffloadTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_cached_transport_encrypted

Tff7b72def Td2a8ffsignature_validatedTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_cached_signature_validated Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_cached_signature_validated
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffloadedTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffloadTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_cached_signature_validated

Tff7b72def Td2a8ffget_signature_descriptionTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffsignature_validatedTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffSignature VerifiedTa5d6ff"
Tff7b72elseTb4b4b4:
Te6edf3reason Tff7b72= Tff7b72selfTff7b72.Td2a8ff_cached_unverified_reason
Tff7b72if Te6edf3reason Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffSOURCE_UNKNOWNTb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffUnknown OriginTa5d6ff"
Tff7b72elif Te6edf3reason Tff7b72== Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffSIGNATURE_INVALIDTb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffInvalid SignatureTa5d6ff"
Tff7b72elseTb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffUnknown signature validation failureTa5d6ff"

Tff7b72def Td2a8ffget_fieldsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffloadedTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffloadTb4b4b4(Tb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8fflxm Tff7b72and Tffa657hasattrTb4b4b4(Tff7b72selfTff7b72.Td2a8fflxmTb4b4b4, Ta5d6ff"Ta5d6ffget_fieldsTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3fields Tff7b72= Tff7b72selfTff7b72.Td2a8fflxmTff7b72.Td2a8ffget_fieldsTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3fields Tff7b72and Tffa657isinstanceTb4b4b4(Te6edf3fieldsTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3fields

Tff7b72return Tb4b4b4{Tb4b4b4}

Tff7b72def Td2a8ffhas_attachmentsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_cached_has_attachments Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_cached_has_attachments
Te6edf3fields Tff7b72= Tff7b72selfTff7b72.Td2a8ffget_fieldsTb4b4b4(Tb4b4b4)
Tff7b72return Tb4b4b4(
Te6edf3LXMFTff7b72.Td2a8ffFIELD_FILE_ATTACHMENTS Tff7b72in Te6edf3fields
Tff7b72or Te6edf3LXMFTff7b72.Td2a8ffFIELD_IMAGE Tff7b72in Te6edf3fields
Tff7b72or Te6edf3LXMFTff7b72.Td2a8ffFIELD_AUDIO Tff7b72in Te6edf3fields
Tb4b4b4)

Tff7b72def Td2a8ffget_file_attachmentsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3att_dir Tff7b72= Tff7b72selfTff7b72.Td2a8ff_attachment_dirTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3att_dir Tff7b72and Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Te6edf3att_dirTb4b4b4)Tb4b4b4:
Te6edf3manifest Tff7b72= Tff7b72selfTff7b72.Td2a8ff_read_attachment_manifestTb4b4b4(Te6edf3att_dirTb4b4b4)
Tff7b72if Te6edf3manifest Tff7b72and Ta5d6ff"Ta5d6fffilesTa5d6ff" Tff7b72in Te6edf3manifestTb4b4b4:
Te6edf3result Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3entry Tff7b72in Te6edf3manifestTb4b4b4[Ta5d6ff"Ta5d6fffilesTa5d6ff"Tb4b4b4]Tb4b4b4:
Te6edf3fpath Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3att_dirTb4b4b4, Te6edf3entryTb4b4b4[Ta5d6ff"Ta5d6ffstored_nameTa5d6ff"Tb4b4b4]Tb4b4b4)
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3fpathTb4b4b4)Tb4b4b4:
Tff7b72with Tffa657openTb4b4b4(Te6edf3fpathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Te6edf3resultTff7b72.Td2a8ffappendTb4b4b4(Tb4b4b4[Te6edf3entryTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4]Tb4b4b4, Te6edf3fTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)Tb4b4b4]Tb4b4b4)
Tff7b72return Te6edf3result

Te6edf3fields Tff7b72= Tff7b72selfTff7b72.Td2a8ffget_fieldsTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffFIELD_FILE_ATTACHMENTSTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4)

Tff7b72def Td2a8ffget_imageTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3att_dir Tff7b72= Tff7b72selfTff7b72.Td2a8ff_attachment_dirTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3att_dir Tff7b72and Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Te6edf3att_dirTb4b4b4)Tb4b4b4:
Te6edf3fpath Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3att_dirTb4b4b4, Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3fpathTb4b4b4)Tb4b4b4:
Tff7b72with Tffa657openTb4b4b4(Te6edf3fpathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Tff7b72return Te6edf3fTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)

Te6edf3fields Tff7b72= Tff7b72selfTff7b72.Td2a8ffget_fieldsTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffFIELD_IMAGETb4b4b4, Tff7b72NoneTb4b4b4)

Tff7b72def Td2a8ffget_audioTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3att_dir Tff7b72= Tff7b72selfTff7b72.Td2a8ff_attachment_dirTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3att_dir Tff7b72and Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Te6edf3att_dirTb4b4b4)Tb4b4b4:
Te6edf3fpath Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3att_dirTb4b4b4, Ta5d6ff"Ta5d6ffaudioTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3fpathTb4b4b4)Tb4b4b4:
Tff7b72with Tffa657openTb4b4b4(Te6edf3fpathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Tff7b72return Te6edf3fTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)

Te6edf3fields Tff7b72= Tff7b72selfTff7b72.Td2a8ffget_fieldsTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffFIELD_AUDIOTb4b4b4, Tff7b72NoneTb4b4b4)

Tff7b72def Td2a8ffget_attachment_file_pathTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3field_typeTb4b4b4, Te6edf3field_indexTff7b72=T79c0ff0Tb4b4b4)Tb4b4b4:
Te6edf3att_dir Tff7b72= Tff7b72selfTff7b72.Td2a8ff_attachment_dirTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3att_dir Tff7b72and Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Te6edf3att_dirTb4b4b4)Tb4b4b4:
Te6edf3manifest Tff7b72= Tff7b72selfTff7b72.Td2a8ff_read_attachment_manifestTb4b4b4(Te6edf3att_dirTb4b4b4)
Tff7b72if Te6edf3manifest Tff7b72and Ta5d6ff"Ta5d6fffilesTa5d6ff" Tff7b72in Te6edf3manifest Tff7b72and Te6edf3field_index Tff7b72< Tffa657lenTb4b4b4(Te6edf3manifestTb4b4b4[Ta5d6ff"Ta5d6fffilesTa5d6ff"Tb4b4b4]Tb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3att_dirTb4b4b4, Te6edf3manifestTb4b4b4[Ta5d6ff"Ta5d6fffilesTa5d6ff"Tb4b4b4]Tb4b4b4[Te6edf3field_indexTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffstored_nameTa5d6ff"Tb4b4b4]Tb4b4b4)
T8b949e# Fallback for old extraction format
Tff7b72if Te6edf3field_type Tff7b72== Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4:
Te6edf3fpath Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3att_dirTb4b4b4, Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3fpathTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3fpath
Tff7b72elif Te6edf3field_type Tff7b72== Ta5d6ff"Ta5d6ffaudioTa5d6ff"Tb4b4b4:
Te6edf3fpath Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3att_dirTb4b4b4, Ta5d6ff"Ta5d6ffaudioTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3fpathTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3fpath
Tff7b72return Tff7b72None

Tff7b72def Td2a8ff_attachment_dirTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3app Tff7b72= Te6edf3nomadnetTff7b72.Td2a8ffNomadNetworkAppTff7b72.Td2a8ffget_shared_instanceTb4b4b4(Tb4b4b4)
Te6edf3msg_hash Tff7b72= Tff7b72selfTff7b72.Td2a8ffget_hashTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3msg_hashTb4b4b4:
Tff7b72return Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3appTff7b72.Td2a8ffattachmentpathTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Te6edf3msg_hashTb4b4b4, Te6edf3delimitTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72pass
Tff7b72return Tff7b72None

Tff7b72def Td2a8ff_read_attachment_manifestTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3att_dirTb4b4b4)Tb4b4b4:
Te6edf3manifest_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3att_dirTb4b4b4, Ta5d6ff"Ta5d6ffmanifestTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3manifest_pathTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72with Tffa657openTb4b4b4(Te6edf3manifest_pathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Te6edf3manifest Tff7b72= Te6edf3msgpackTff7b72.Td2a8ffunpackbTb4b4b4(Te6edf3fTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3rawTff7b72=Tff7b72FalseTb4b4b4)
Te6edf3safe_files Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3idxTb4b4b4, Te6edf3entry Tff7b72in Tffa657enumerateTb4b4b4(Te6edf3manifestTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fffilesTa5d6ff"Tb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3entryTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72continue
Te6edf3entryTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3ConversationMessageTff7b72.Td2a8ffsafe_attachment_nameTb4b4b4(Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4)Tb4b4b4, Te6edf3fallbackTff7b72=Ta5d6ff"Ta5d6ffattachment_Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3idxTb4b4b4)Tb4b4b4)
Te6edf3stored Tff7b72= Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffstored_nameTa5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3storedTb4b4b4, Tffa657strTb4b4b4) Tff7b72or Tff7b72not Te6edf3reTff7b72.Td2a8fffullmatchTb4b4b4(Ta5d6ffrTa5d6ff"Ta5d6fffile_Ta5d6ff\Ta5d6ffd+Ta5d6ff"Tb4b4b4, Te6edf3storedTb4b4b4)Tb4b4b4:
Tff7b72continue
Te6edf3safe_filesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3entryTb4b4b4)
Te6edf3manifestTb4b4b4[Ta5d6ff"Ta5d6fffilesTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3safe_files
Tff7b72return Te6edf3manifest

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError loading attachment manifest: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4)
Tff7b72return Tff7b72None

Tff7b72return Tff7b72None

Tf0883e@staticmethod
Tff7b72def Td2a8ffextract_attachments_from_lxmTb4b4b4(Te6edf3lxmessageTb4b4b4, Te6edf3appTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tffa657hasattrTb4b4b4(Te6edf3lxmessageTb4b4b4, Ta5d6ff"Ta5d6ffget_fieldsTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72return
Te6edf3fields Tff7b72= Te6edf3lxmessageTff7b72.Td2a8ffget_fieldsTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3fields Tff7b72or Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3fieldsTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72return

Te6edf3has_any Tff7b72= Tb4b4b4(
Te6edf3LXMFTff7b72.Td2a8ffFIELD_FILE_ATTACHMENTS Tff7b72in Te6edf3fields
Tff7b72or Te6edf3LXMFTff7b72.Td2a8ffFIELD_IMAGE Tff7b72in Te6edf3fields
Tff7b72or Te6edf3LXMFTff7b72.Td2a8ffFIELD_AUDIO Tff7b72in Te6edf3fields
Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3has_anyTb4b4b4:
Tff7b72return

Te6edf3msg_hash_hex Tff7b72= Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Te6edf3lxmessageTff7b72.Td2a8ffhashTb4b4b4, Te6edf3delimitTff7b72=Tff7b72FalseTb4b4b4)
Te6edf3att_dir Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3appTff7b72.Td2a8ffattachmentpathTb4b4b4, Te6edf3msg_hash_hexTb4b4b4)
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Te6edf3att_dirTb4b4b4)Tb4b4b4:
Tff7b72return

Te6edf3osTff7b72.Td2a8ffmakedirsTb4b4b4(Te6edf3att_dirTb4b4b4)
Te6edf3manifest Tff7b72= Tb4b4b4{Ta5d6ff"Ta5d6fffilesTa5d6ff"Tb4b4b4: Tb4b4b4[Tb4b4b4]Tb4b4b4}

Te6edf3file_attachments Tff7b72= Te6edf3fieldsTff7b72.Td2a8ffgetTb4b4b4(Te6edf3LXMFTff7b72.Td2a8ffFIELD_FILE_ATTACHMENTSTb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4)
Tff7b72if Te6edf3file_attachmentsTb4b4b4:
Tff7b72for Te6edf3idxTb4b4b4, Te6edf3att Tff7b72in Tffa657enumerateTb4b4b4(Te6edf3file_attachmentsTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3attTb4b4b4, Tffa657listTb4b4b4) Tff7b72and Tffa657lenTb4b4b4(Te6edf3attTb4b4b4) Tff7b72>Tff7b72= T79c0ff2Tb4b4b4:
Te6edf3filename Tff7b72= Te6edf3ConversationMessageTff7b72.Td2a8ffsafe_attachment_nameTb4b4b4(Te6edf3attTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4, Te6edf3fallbackTff7b72=Ta5d6ff"Ta5d6ffattachment_Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3idxTb4b4b4)Tb4b4b4)
Te6edf3data Tff7b72= Te6edf3attTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3attTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4, Tffa657bytesTb4b4b4) Tff7b72else Ta5d6ffbTa5d6ff"Ta5d6ff"
Te6edf3stored_name Tff7b72= Ta5d6ff"Ta5d6fffile_Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3idxTb4b4b4)
Tff7b72with Tffa657openTb4b4b4(Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3att_dirTb4b4b4, Te6edf3stored_nameTb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4: Te6edf3fTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3dataTb4b4b4)
Te6edf3manifestTb4b4b4[Ta5d6ff"Ta5d6fffilesTa5d6ff"Tb4b4b4]Tff7b72.Td2a8ffappendTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Te6edf3filenameTb4b4b4, Ta5d6ff"Ta5d6ffstored_nameTa5d6ff"Tb4b4b4: Te6edf3stored_nameTb4b4b4, Ta5d6ff"Ta5d6ffsizeTa5d6ff"Tb4b4b4: Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4}Tb4b4b4)

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError decoding file attachment: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72continue

Tff7b72if Te6edf3LXMFTff7b72.Td2a8ffFIELD_IMAGE Tff7b72in Te6edf3fieldsTb4b4b4:
Te6edf3fmtTb4b4b4, Te6edf3data Tff7b72= Te6edf3ConversationMessageTff7b72.Td2a8ff_unpack_media_fieldTb4b4b4(Te6edf3fieldsTb4b4b4[Te6edf3LXMFTff7b72.Td2a8ffFIELD_IMAGETb4b4b4]Tb4b4b4)
Tff7b72if Te6edf3dataTb4b4b4:
Te6edf3ext Tff7b72= Te6edf3ConversationMessageTff7b72.Td2a8ff_ext_from_media_formatTb4b4b4(Te6edf3fmtTb4b4b4, Te6edf3dataTb4b4b4)
Te6edf3filename Tff7b72= Te6edf3ConversationMessageTff7b72.Td2a8ffsafe_attachment_nameTb4b4b4(Ta5d6ff"Ta5d6ffimageTa5d6ff" Tff7b72+ Te6edf3extTb4b4b4, Te6edf3fallbackTff7b72=Ta5d6ff"Ta5d6ffimageTa5d6ff"Tb4b4b4)
Te6edf3stored_name Tff7b72= Ta5d6ff"Ta5d6fffile_Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tffa657lenTb4b4b4(Te6edf3manifestTb4b4b4[Ta5d6ff"Ta5d6fffilesTa5d6ff"Tb4b4b4]Tb4b4b4)Tb4b4b4)
Tff7b72with Tffa657openTb4b4b4(Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3att_dirTb4b4b4, Te6edf3stored_nameTb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Te6edf3fTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3dataTb4b4b4)
Te6edf3manifestTb4b4b4[Ta5d6ff"Ta5d6fffilesTa5d6ff"Tb4b4b4]Tff7b72.Td2a8ffappendTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Te6edf3filenameTb4b4b4, Ta5d6ff"Ta5d6ffstored_nameTa5d6ff"Tb4b4b4: Te6edf3stored_nameTb4b4b4, Ta5d6ff"Ta5d6ffsizeTa5d6ff"Tb4b4b4: Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4}Tb4b4b4)

Tff7b72if Te6edf3LXMFTff7b72.Td2a8ffFIELD_AUDIO Tff7b72in Te6edf3fieldsTb4b4b4:
Te6edf3fmtTb4b4b4, Te6edf3data Tff7b72= Te6edf3ConversationMessageTff7b72.Td2a8ff_unpack_media_fieldTb4b4b4(Te6edf3fieldsTb4b4b4[Te6edf3LXMFTff7b72.Td2a8ffFIELD_AUDIOTb4b4b4]Tb4b4b4)
Tff7b72if Te6edf3dataTb4b4b4:
Te6edf3ext Tff7b72= Te6edf3ConversationMessageTff7b72.Td2a8ff_ext_from_media_formatTb4b4b4(Te6edf3fmtTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3is_audioTff7b72=Tff7b72TrueTb4b4b4)
Te6edf3filename Tff7b72= Te6edf3ConversationMessageTff7b72.Td2a8ffsafe_attachment_nameTb4b4b4(Ta5d6ff"Ta5d6ffaudioTa5d6ff" Tff7b72+ Te6edf3extTb4b4b4, Te6edf3fallbackTff7b72=Ta5d6ff"Ta5d6ffaudioTa5d6ff"Tb4b4b4)
Te6edf3stored_name Tff7b72= Ta5d6ff"Ta5d6fffile_Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tffa657lenTb4b4b4(Te6edf3manifestTb4b4b4[Ta5d6ff"Ta5d6fffilesTa5d6ff"Tb4b4b4]Tb4b4b4)Tb4b4b4)
Tff7b72with Tffa657openTb4b4b4(Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3att_dirTb4b4b4, Te6edf3stored_nameTb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Te6edf3fTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3dataTb4b4b4)
Te6edf3manifestTb4b4b4[Ta5d6ff"Ta5d6fffilesTa5d6ff"Tb4b4b4]Tff7b72.Td2a8ffappendTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Te6edf3filenameTb4b4b4, Ta5d6ff"Ta5d6ffstored_nameTa5d6ff"Tb4b4b4: Te6edf3stored_nameTb4b4b4, Ta5d6ff"Ta5d6ffsizeTa5d6ff"Tb4b4b4: Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4}Tb4b4b4)

Tff7b72with Tffa657openTb4b4b4(Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3att_dirTb4b4b4, Ta5d6ff"Ta5d6ffmanifestTa5d6ff"Tb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Te6edf3fTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3msgpackTff7b72.Td2a8ffpackbTb4b4b4(Te6edf3manifestTb4b4b4)Tb4b4b4)

Tf0883e@staticmethod
Tff7b72def Td2a8ffsafe_attachment_nameTb4b4b4(Te6edf3nameTb4b4b4, Te6edf3fallbackTff7b72=Ta5d6ff"Ta5d6ffattachmentTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3nameTb4b4b4, Tffa657bytesTb4b4b4)Tb4b4b4:
Te6edf3name Tff7b72= Te6edf3nameTff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4, Te6edf3errorsTff7b72=Ta5d6ff"Ta5d6ffreplaceTa5d6ff"Tb4b4b4)
Tff7b72elif Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3nameTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4:
Te6edf3name Tff7b72= Tffa657strTb4b4b4(Te6edf3nameTb4b4b4) Tff7b72if Te6edf3name Tff7b72is Tff7b72not Tff7b72None Tff7b72else Ta5d6ff"Ta5d6ff"
Tff7b72except Tf85149ExceptionTb4b4b4:
Te6edf3name Tff7b72= Ta5d6ff"Ta5d6ff"
Te6edf3name Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff"Ta5d6ff[Ta5d6ff\Ta5d6ffx00-Ta5d6ff\Ta5d6ffx1fTa5d6ff\Ta5d6ffx7f]Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4, Te6edf3nameTb4b4b4)
Te6edf3parts Tff7b72= Te6edf3reTff7b72.Td2a8ffsplitTb4b4b4(Ta5d6ffrTa5d6ff"Ta5d6ff[/Tffea00\\Ta5d6ff]Ta5d6ff"Tb4b4b4, Te6edf3nameTb4b4b4)
Te6edf3name Tff7b72= Te6edf3partsTb4b4b4[Tff7b72-T79c0ff1Tb4b4b4] Tff7b72if Te6edf3parts Tff7b72else Ta5d6ff"Ta5d6ff"
Tff7b72if Ta5d6ff"Ta5d6ff:Ta5d6ff" Tff7b72in Te6edf3nameTb4b4b4:
Te6edf3name Tff7b72= Te6edf3nameTff7b72.Td2a8ffsplitTb4b4b4(Ta5d6ff"Ta5d6ff:Ta5d6ff"Tb4b4b4)Tb4b4b4[Tff7b72-T79c0ff1Tb4b4b4]
Te6edf3name Tff7b72= Te6edf3nameTff7b72.Td2a8fflstripTb4b4b4(Ta5d6ff"Ta5d6ff.Ta5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3name Tff7b72or Te6edf3name Tff7b72in Tb4b4b4(Ta5d6ff"Ta5d6ff.Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff..Ta5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3fallback
Tff7b72if Tffa657lenTb4b4b4(Te6edf3nameTb4b4b4) Tff7b72> T79c0ff200Tb4b4b4:
Te6edf3baseTb4b4b4, Te6edf3ext Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffsplitextTb4b4b4(Te6edf3nameTb4b4b4)
Te6edf3ext Tff7b72= Te6edf3extTb4b4b4[Tb4b4b4:T79c0ff16Tb4b4b4]
Te6edf3name Tff7b72= Te6edf3baseTb4b4b4[Tb4b4b4:T79c0ff200 Tff7b72- Tffa657lenTb4b4b4(Te6edf3extTb4b4b4)Tb4b4b4] Tff7b72+ Te6edf3ext
Tff7b72return Te6edf3name

Tf0883e@staticmethod
Tff7b72def Td2a8ff_unpack_media_fieldTb4b4b4(Te6edf3field_dataTb4b4b4)Tb4b4b4:
T8b949e"""Normalize FIELD_IMAGE/FIELD_AUDIO which can be raw bytes or [format, bytes].
Format element can be a string ('webp') or integer (LXMF audio mode constant)."""
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3field_dataTb4b4b4, Tffa657bytesTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72NoneTb4b4b4, Te6edf3field_data
Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3field_dataTb4b4b4, Tffa657listTb4b4b4) Tff7b72and Tffa657lenTb4b4b4(Te6edf3field_dataTb4b4b4) Tff7b72>Tff7b72= T79c0ff2 Tff7b72and Tffa657isinstanceTb4b4b4(Te6edf3field_dataTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4, Tffa657bytesTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3field_dataTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4, Te6edf3field_dataTb4b4b4[T79c0ff1Tb4b4b4]
Tff7b72return Tff7b72NoneTb4b4b4, Tff7b72None

Tf0883e@staticmethod
Tff7b72def Td2a8ff_detect_image_extTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3dataTb4b4b4, Tffa657bytesTb4b4b4) Tff7b72or Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4) Tff7b72< T79c0ff12Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff.binTa5d6ff"
Tff7b72if Te6edf3dataTb4b4b4[Tb4b4b4:T79c0ff8Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff'Tffea00\x89Ta5d6ffPNGTffea00\rTffea00\nTffea00\x1aTffea00\nTa5d6ff'Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff.pngTa5d6ff"
Tff7b72elif Te6edf3dataTb4b4b4[Tb4b4b4:T79c0ff3Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff'Tffea00\xffTffea00\xd8Tffea00\xffTa5d6ff'Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff.jpgTa5d6ff"
Tff7b72elif Te6edf3dataTb4b4b4[Tb4b4b4:T79c0ff4Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff'Ta5d6ffGIF8Ta5d6ff'Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff.gifTa5d6ff"
Tff7b72elif Te6edf3dataTb4b4b4[Tb4b4b4:T79c0ff4Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff'Ta5d6ffRIFFTa5d6ff' Tff7b72and Te6edf3dataTb4b4b4[T79c0ff8Tb4b4b4:T79c0ff12Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff'Ta5d6ffWEBPTa5d6ff'Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff.webpTa5d6ff"
Tff7b72elif Te6edf3dataTb4b4b4[Tb4b4b4:T79c0ff4Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff'Tffea00\x00Tffea00\x00Tffea00\x00Tffea00\x1cTa5d6ff' Tff7b72or Te6edf3dataTb4b4b4[Tb4b4b4:T79c0ff4Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff'Tffea00\x00Tffea00\x00Tffea00\x00Tffea00\x18Ta5d6ff'Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff.heicTa5d6ff"
Tff7b72return Ta5d6ff"Ta5d6ff.binTa5d6ff"

Tf0883e@staticmethod
Tff7b72def Td2a8ff_detect_audio_extTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3dataTb4b4b4, Tffa657bytesTb4b4b4) Tff7b72or Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4) Tff7b72< T79c0ff12Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff.binTa5d6ff"
Tff7b72if Te6edf3dataTb4b4b4[Tb4b4b4:T79c0ff4Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff'Ta5d6ffOggSTa5d6ff'Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff.oggTa5d6ff"
Tff7b72elif Te6edf3dataTb4b4b4[Tb4b4b4:T79c0ff2Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff'Tffea00\xffTffea00\xfbTa5d6ff' Tff7b72or Te6edf3dataTb4b4b4[Tb4b4b4:T79c0ff3Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff'Ta5d6ffID3Ta5d6ff'Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff.mp3Ta5d6ff"
Tff7b72elif Te6edf3dataTb4b4b4[Tb4b4b4:T79c0ff4Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff'Ta5d6ffRIFFTa5d6ff' Tff7b72and Te6edf3dataTb4b4b4[T79c0ff8Tb4b4b4:T79c0ff12Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff'Ta5d6ffWAVETa5d6ff'Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff.wavTa5d6ff"
Tff7b72elif Te6edf3dataTb4b4b4[Tb4b4b4:T79c0ff4Tb4b4b4] Tff7b72== Ta5d6ffbTa5d6ff'Ta5d6fffLaCTa5d6ff'Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff.flacTa5d6ff"
Tff7b72return Ta5d6ff"Ta5d6ff.binTa5d6ff"

Tf0883e@staticmethod
Tff7b72def Td2a8ff_ext_from_media_formatTb4b4b4(Te6edf3fmtTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3is_audioTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3fmtTb4b4b4, Tffa657strTb4b4b4) Tff7b72and Tffa657lenTb4b4b4(Te6edf3fmtTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3safe Tff7b72= Te6edf3reTff7b72.Td2a8ffsubTb4b4b4(Ta5d6ffrTa5d6ff"Ta5d6ff[^A-Za-z0-9]Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4, Te6edf3fmtTb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)Tb4b4b4[Tb4b4b4:T79c0ff8Tb4b4b4]
Tff7b72if Te6edf3safeTb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff.Ta5d6ff" Tff7b72+ Te6edf3safe
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3fmtTb4b4b4, Tffa657intTb4b4b4) Tff7b72and Te6edf3is_audioTb4b4b4:
Tff7b72if Te6edf3fmt Tff7b72>Tff7b72= T79c0ff16 Tff7b72and Te6edf3fmt Tff7b72<Tff7b72= T79c0ff25Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff.oggTa5d6ff"
Tff7b72elif Te6edf3fmt Tff7b72>Tff7b72= T79c0ff1 Tff7b72and Te6edf3fmt Tff7b72<Tff7b72= T79c0ff9Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff.c2Ta5d6ff"
Tff7b72if Te6edf3is_audioTb4b4b4:
Tff7b72return Te6edf3ConversationMessageTff7b72.Td2a8ff_detect_audio_extTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72return Te6edf3ConversationMessageTff7b72.Td2a8ff_detect_image_extTb4b4b4(Te6edf3dataTb4b4b4)

Tf0883e@staticmethod
Tff7b72def Td2a8ffstrip_attachments_from_fileTb4b4b4(Te6edf3file_pathTb4b4b4, Te6edf3appTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72with Tffa657openTb4b4b4(Te6edf3file_pathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Te6edf3container Tff7b72= Te6edf3msgpackTff7b72.Td2a8ffunpackbTb4b4b4(Te6edf3fTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3strict_map_keyTff7b72=Tff7b72FalseTb4b4b4)

Te6edf3lxmf_bytes Tff7b72= Te6edf3containerTb4b4b4[Ta5d6ffbTa5d6ff"Ta5d6fflxmf_bytesTa5d6ff"Tb4b4b4] Tff7b72if Ta5d6ffbTa5d6ff"Ta5d6fflxmf_bytesTa5d6ff" Tff7b72in Te6edf3container Tff7b72else Te6edf3containerTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fflxmf_bytesTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3lxmf_bytes Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return

Te6edf3dest_len Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffDESTINATION_LENGTH
Te6edf3sig_len Tff7b72= Te6edf3LXMFTff7b72.Td2a8ffLXMessageTff7b72.Td2a8ffSIGNATURE_LENGTH
Te6edf3header_len Tff7b72= T79c0ff2 Tff7b72* Te6edf3dest_len Tff7b72+ Te6edf3sig_len

Te6edf3header Tff7b72= Te6edf3lxmf_bytesTb4b4b4[Tb4b4b4:Te6edf3header_lenTb4b4b4]
Te6edf3payload_bytes Tff7b72= Te6edf3lxmf_bytesTb4b4b4[Te6edf3header_lenTb4b4b4:Tb4b4b4]
Te6edf3payload Tff7b72= Te6edf3msgpackTff7b72.Td2a8ffunpackbTb4b4b4(Te6edf3payload_bytesTb4b4b4, Te6edf3strict_map_keyTff7b72=Tff7b72FalseTb4b4b4)

Tff7b72if Tffa657lenTb4b4b4(Te6edf3payloadTb4b4b4) Tff7b72< T79c0ff4 Tff7b72or Tff7b72not Tffa657isinstanceTb4b4b4(Te6edf3payloadTb4b4b4[T79c0ff3Tb4b4b4]Tb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72return

Te6edf3fields Tff7b72= Te6edf3payloadTb4b4b4[T79c0ff3Tb4b4b4]
Te6edf3attachment_keys Tff7b72= Tb4b4b4[Te6edf3LXMFTff7b72.Td2a8ffFIELD_FILE_ATTACHMENTSTb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffFIELD_IMAGETb4b4b4, Te6edf3LXMFTff7b72.Td2a8ffFIELD_AUDIOTb4b4b4]
Tff7b72if Tff7b72not Tffa657anyTb4b4b4(Te6edf3k Tff7b72in Te6edf3fields Tff7b72for Te6edf3k Tff7b72in Te6edf3attachment_keysTb4b4b4)Tb4b4b4:
Tff7b72return

T8b949e# Compute message hash matching LXMF's logic
Tff7b72if Tffa657lenTb4b4b4(Te6edf3payloadTb4b4b4) Tff7b72> T79c0ff4Tb4b4b4:
Te6edf3hash_payload Tff7b72= Te6edf3msgpackTff7b72.Td2a8ffpackbTb4b4b4(Te6edf3payloadTb4b4b4[Tb4b4b4:T79c0ff4Tb4b4b4]Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3hash_payload Tff7b72= Te6edf3payload_bytes
Te6edf3msg_hash Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffull_hashTb4b4b4(Te6edf3lxmf_bytesTb4b4b4[Tb4b4b4:T79c0ff2Tff7b72*Te6edf3dest_lenTb4b4b4] Tff7b72+ Te6edf3hash_payloadTb4b4b4)
Te6edf3msg_hash_hex Tff7b72= Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Te6edf3msg_hashTb4b4b4, Te6edf3delimitTff7b72=Tff7b72FalseTb4b4b4)

Te6edf3att_dir Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3appTff7b72.Td2a8ffattachmentpathTb4b4b4, Te6edf3msg_hash_hexTb4b4b4)
Tff7b72if Tff7b72not Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Te6edf3att_dirTb4b4b4)Tb4b4b4:
Tff7b72return

Tff7b72for Te6edf3k Tff7b72in Te6edf3attachment_keysTb4b4b4:
Tff7b72if Te6edf3k Tff7b72in Te6edf3fieldsTb4b4b4:
Tff7b72del Te6edf3fieldsTb4b4b4[Te6edf3kTb4b4b4]

Te6edf3new_lxmf_bytes Tff7b72= Te6edf3header Tff7b72+ Te6edf3msgpackTff7b72.Td2a8ffpackbTb4b4b4(Te6edf3payloadTb4b4b4)
Te6edf3key Tff7b72= Ta5d6ffbTa5d6ff"Ta5d6fflxmf_bytesTa5d6ff" Tff7b72if Ta5d6ffbTa5d6ff"Ta5d6fflxmf_bytesTa5d6ff" Tff7b72in Te6edf3container Tff7b72else Ta5d6ff"Ta5d6fflxmf_bytesTa5d6ff"
Te6edf3containerTb4b4b4[Te6edf3keyTb4b4b4] Tff7b72= Te6edf3new_lxmf_bytes

Tff7b72with Tffa657openTb4b4b4(Te6edf3file_pathTb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Te6edf3fTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3msgpackTff7b72.Td2a8ffpackbTb4b4b4(Te6edf3containerTb4b4b4)Tb4b4b4)

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError stripping attachments from LXM file: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72def Td2a8ffto_index_entryTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tb4b4b4{
Ta5d6ff"Ta5d6fftimestampTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8fftimestampTb4b4b4,
Ta5d6ff"Ta5d6ffsort_timestampTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffsort_timestampTb4b4b4,
Ta5d6ff"Ta5d6ffstateTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ff_cached_stateTb4b4b4,
Ta5d6ff"Ta5d6fftitleTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ff_cached_titleTb4b4b4,
Ta5d6ff"Ta5d6ffcontentTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ff_cached_contentTb4b4b4,
Ta5d6ff"Ta5d6ffsource_hashTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ff_cached_source_hashTb4b4b4,
Ta5d6ff"Ta5d6fftransport_encryptedTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ff_cached_transport_encryptedTb4b4b4,
Ta5d6ff"Ta5d6fftransport_encryptionTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ff_cached_transport_encryptionTb4b4b4,
Ta5d6ff"Ta5d6ffsignature_validatedTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ff_cached_signature_validatedTb4b4b4,
Ta5d6ff"Ta5d6ffunverified_reasonTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ff_cached_unverified_reasonTb4b4b4,
Ta5d6ff"Ta5d6ffmethodTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ff_cached_methodTb4b4b4,
Ta5d6ff"Ta5d6ffhas_attachmentsTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ff_cached_has_attachmentsTb4b4b4,
Ta5d6ff"Ta5d6ffattachment_namesTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ff_cached_attachment_namesTb4b4b4,
Tb4b4b4}

Tff7b72def Td2a8ffrestore_from_indexTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3entryTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8fftimestamp Tff7b72= Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fftimestampTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffsort_timestamp Tff7b72= Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffsort_timestampTa5d6ff"Tb4b4b4, Tff7b72selfTff7b72.Td2a8ffsort_timestampTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_cached_state Tff7b72= Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffstateTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_cached_title Tff7b72= Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fftitleTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_cached_content Tff7b72= Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffcontentTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_cached_source_hash Tff7b72= Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffsource_hashTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_cached_transport_encrypted Tff7b72= Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fftransport_encryptedTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_cached_transport_encryption Tff7b72= Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fftransport_encryptionTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_cached_signature_validated Tff7b72= Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffsignature_validatedTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_cached_unverified_reason Tff7b72= Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffunverified_reasonTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_cached_method Tff7b72= Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffmethodTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_cached_has_attachments Tff7b72= Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhas_attachmentsTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_cached_attachment_names Tff7b72= Te6edf3entryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffattachment_namesTa5d6ff"Tb4b4b4)

Tf0883e@staticmethod
Tff7b72def Td2a8ffread_indexTb4b4b4(Te6edf3conversation_pathTb4b4b4)Tb4b4b4:
Te6edf3index_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3conversation_pathTb4b4b4, Ta5d6ff"Ta5d6ff.indexTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3index_pathTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72with Tffa657openTb4b4b4(Te6edf3index_pathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Tff7b72return Te6edf3msgpackTff7b72.Td2a8ffunpackbTb4b4b4(Te6edf3fTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3rawTff7b72=Tff7b72FalseTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72pass
Tff7b72return Tb4b4b4{Tb4b4b4}

Tf0883e@staticmethod
Tff7b72def Td2a8ffwrite_indexTb4b4b4(Te6edf3conversation_pathTb4b4b4, Te6edf3messagesTb4b4b4)Tb4b4b4:
Te6edf3index_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3conversation_pathTb4b4b4, Ta5d6ff"Ta5d6ff.indexTa5d6ff"Tb4b4b4)
Te6edf3index Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3index_pathTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72with Tffa657openTb4b4b4(Te6edf3index_pathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Te6edf3index Tff7b72= Te6edf3msgpackTff7b72.Td2a8ffunpackbTb4b4b4(Te6edf3fTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3rawTff7b72=Tff7b72FalseTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Te6edf3index Tff7b72= Tb4b4b4{Tb4b4b4}

Tff7b72for Te6edf3msg Tff7b72in Te6edf3messagesTb4b4b4:
Tff7b72if Te6edf3msgTff7b72.Td2a8ff_cached_state Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3filename Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffbasenameTb4b4b4(Te6edf3msgTff7b72.Td2a8fffile_pathTb4b4b4)
Te6edf3indexTb4b4b4[Te6edf3filenameTb4b4b4] Tff7b72= Te6edf3msgTff7b72.Td2a8ffto_index_entryTb4b4b4(Tb4b4b4)

Tff7b72tryTb4b4b4:
Tff7b72with Tffa657openTb4b4b4(Te6edf3index_pathTb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4:
Te6edf3fTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3msgpackTff7b72.Td2a8ffpackbTb4b4b4(Te6edf3indexTb4b4b4)Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError writing conversation index: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────